package com.demo.tankGame04;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

/**
 * 绘制坦克的面版
 *
 * @author gy
 * @date 2022/4/18
 */
public class MyPanel extends JPanel implements KeyListener, Runnable {

    private Hero hero;

    Vector<EnemyTank> enemyTanks = new Vector<>();

    // 定义一个Vector 用于存放炸弹
    // 说明：当子弹击中坦克时，加入一个Bomb对象到 bombs
    Vector<Bomb> bombs = new Vector<>();

    private int enemyTankSize = 3;

    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    /**
     * 初始化面板，将自己的坦克，
     * <p>
     * 和敌人的坦克构造出来，在构造敌人的坦克时，将敌人坦克的 shot 构造出来
     * <p>
     * 初始化图片对象
     */
    public MyPanel() {
//        ============================================
        this.hero = new Hero(600, 100);
        // 自定义坦克的速度
        hero.setSpeed(5);
//          ===========================================

        for (int i = 0; i < enemyTankSize; i++) {
            // 在不同的位置定义敌人的坦克
            EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
            // 让敌人的坦克 都炮筒朝下，敌人坦克的属性，最好在初始化的时候都安排好
            enemyTank.setDirect(2);

            // 在创建敌人的坦克时，让它自由的移动
            new Thread(enemyTank).start();

            //给 敌人的坦克 添加子弹
            Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
            // 加入 enemyTank 的 vector 成员中
            enemyTank.shots.add(shot);
            // 启动 shot 对象
            new Thread(shot).start();

            // 将初始化好的坦克，添加到 敌人的坦克的 集合中去,方便我们绘制坦克
            enemyTanks.add(enemyTank);
        }
        // 初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb1.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb2.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb3.png"));
    }

    /**
     * 将初始化好的 坦克，绘制出来
     *
     * @param g 画笔
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
//        ==============================================
        g.fillRect(0, 0, 1000, 750);

        if(hero != null && hero.isLive) {
            // 画出自己的坦克-封装方法
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
        }

        // 画出自己的坦克的子弹
//        if (hero.shot != null && hero.shot.isLive == true) {
//            System.out.println("子弹被绘制");
//            g.draw3DRect(hero.shot.x, hero.shot.y, 2, 2, false);
//        }

        // 画出一梭子子弹
        for (int i = 0; i < hero.shots.size(); i++) {
            Shot shot = hero.shots.get(i);
            if (shot != null && shot.isLive == true) {
                System.out.println("子弹被绘制");
                g.draw3DRect(shot.x, shot.y, 2, 2, false);
            } else {
                // 如果该子弹已经失效了
                hero.shots.remove(shot);
            }
        }


        // 如果bomb中有对象，就画出来
        // 注意初始化的顺序也很重要，一定要 先有爆炸效果，敌人的坦克才会消失
        for (int i = 0; i < bombs.size(); i++) {
            // 取出子弹
            Bomb bomb = bombs.get(i);
            // 根据当前这个bombs对象的life只去画出对那个的图片
            if (bomb.life > 6) {
                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
            } else if (bomb.life > 3) {
                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
            } else {
                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
            }
            // 这让炸弹的生命值减少
            bomb.lifeDown();
            // 如果bomb 的 life为0，就从bomb 的集合中删除
            if (bomb.life == 0) {
                bombs.remove(bomb);
            }
        }
//        ================================================
        // 画出敌人的坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            // 只有在敌人的 坦克在 活着的时候，才去绘制它
            if (enemyTank.isLive) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);

                // 画出敌人坦克的所有子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    Shot shot = enemyTank.shots.get(j);
                    if (shot.isLive) {
                        g.draw3DRect(shot.x, shot.y, 2, 2, false);
                    } else {
                        // 将销毁的子弹从 Vector(可以保证线程安全) 中去除
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }
    }

    /**
     * 绘制 坦克
     *
     * @param x      起始横坐标
     * @param y      起始纵坐标
     * @param g      画笔
     * @param direct 方向 0:向上 1:向右 2:向下 3:向左
     * @param type   颜色类型 0:敌人 1: 自己
     */
    public void drawTank(int x, int y, Graphics g, int direct, int type) {
        // 根据不同的颜色绘制坦克
        switch (type) {
            case 0:
                g.setColor(Color.cyan);// 敌人坦克
                break;
            case 1:
                g.setColor(Color.yellow); // 自己坦克
                break;
            default:
        }
        // 根据不同的方向绘制坦克
        switch (direct) {
            case 0:
                g.fill3DRect(x, y, 10, 60, false);// 画出坦克左轮
                g.fill3DRect(x + 30, y, 10, 60, false);// 画出坦克右轮
                g.fill3DRect(x + 10, y + 10, 20, 40, false);// 画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);// 画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y);// 画出炮筒
                break;
            case 1:
                g.fill3DRect(x, y, 60, 10, false);// 画出坦克左轮
                g.fill3DRect(x, y + 30, 60, 10, false);// 画出坦克右轮
                g.fill3DRect(x + 10, y + 10, 40, 20, false);// 画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);// 画出圆形盖子
                g.drawLine(x + 30, y + 20, x + 60, y + 20);// 画出炮筒
                break;
            case 2:
                g.fill3DRect(x, y, 10, 60, false);// 画出坦克左轮
                g.fill3DRect(x + 30, y, 10, 60, false);// 画出坦克右轮
                g.fill3DRect(x + 10, y + 10, 20, 40, false);// 画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);// 画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y + 60);// 画出炮筒
                break;
            case 3:
                g.fill3DRect(x, y, 60, 10, false);// 画出坦克左轮
                g.fill3DRect(x, y + 30, 60, 10, false);// 画出坦克右轮
                g.fill3DRect(x + 10, y + 10, 40, 20, false);// 画出坦克盖子
                g.fillOval(x + 20, y + 10, 20, 20);// 画出圆形盖子
                g.drawLine(x + 30, y + 20, x, y + 20);// 画出炮筒
                break;
            default:
                System.out.println("暂时没做处理");
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            hero.setDirect(0);
            if (hero.getY() > 0) {
                hero.moveUp(); // 开始移动
            }
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            hero.setDirect(1);
            if (hero.getX() + 60 < 1000) {
                hero.moveRight();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            hero.setDirect(2);
            if (hero.getY() + 60 < 750) {
                hero.moveDown();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            hero.setDirect(3);
            if (hero.getX() > 0) {
                hero.moveLeft();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            // 开始发射子弹
            // 如果子弹消亡后，在创建 !hero.shot.isLive !(false) == true
            // 发射一一颗子弹
//            if(hero.shot == null || !hero.shot.isLive) {
//                hero.shotEnemyTank();
//            }
            // 发射多颗子弹
            hero.shotEnemyTank();
        }
        // 让面板重画
        this.repaint();
    }

    /**
     * 如果我们的坦克可以发射多颗子弹
     * 在判断我方子弹是否击中敌人坦克时，就需要把我们的子弹集合中所有的子弹
     * 全部取出，和敌人的所有坦克进行判断
     */
    public void hiEnemyTank() {
        for (int i = 0; i < hero.shots.size(); i++) {
            Shot shot = hero.shots.get(i);
            // 判断是否击中了敌人的坦克
            if (shot != null && shot.isLive) { // 当我方的子弹还存活
                // 遍历所有敌人的坦克
                for (int j = 0; j < enemyTanks.size(); j++) {
                    EnemyTank enemyTank = enemyTanks.get(j);
                    // 每次都判断是否击中了敌人的坦克
                    hiTank(shot, enemyTank);
                }
            }
        }
    }

    // 编写方法，判断敌人坦克是否击中我方坦克
    public void hitHero() {
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                Shot shot = enemyTank.shots.get(j);
                // 自己 和 敌人子弹都活着
                if(hero.isLive && shot.isLive) {
                    hiTank(shot, hero);
                }
            }
        }
    }


    // 编写方法，判断我方的子弹是否击中 敌人的 坦克。
    // 什么时候 去判断呢？ run方法
    // 后面将 tank 形参名改变
    // 此方法就判断了 子弹 是否 击中坦克
    public void hiTank(Shot s, Tank enemyTank) {

        switch (enemyTank.getDirect()) {
            case 0:
            case 2:
                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40
                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60) {
                    s.isLive = false;
                    enemyTank.isLive = false;

                    // 当我们的子弹击中地方的坦克后，将enemyTank 从 Vector集合中去掉
                    enemyTanks.remove(enemyTank);

                    // 创建bomb对象，加入到bombs集合中
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);


//                    // 此处优化：敌人坦克销毁后，它之前创建的子弹并未销毁，需要将子弹同样销毁
//                    for (int i = 0; i < enemyTank.shots.size(); i++) {
//                        Shot enemyShot = enemyTank.shots.get(i);
//                        enemyShot.isLive = false;
//                    }

                }
                break;
            case 1:
            case 3:
                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60
                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40) {
                    s.isLive = false;
                    enemyTank.isLive = false;

                    // 创建bomb对象，加入到bombs集合中
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);


//                    // 此处优化：敌人坦克销毁后，它之前创建的子弹并未销毁，需要将子弹同样销毁
//                    for (int i = 0; i < enemyTank.shots.size(); i++) {
//                        Shot enemyShot = enemyTank.shots.get(i);
//                        enemyShot.isLive = false;
//                    }

                }
                break;
            default:
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true) {
            try {
//                System.out.println(Thread.currentThread().getName() + "-线程正在运行中");
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 判断我们子弹是否击中了敌人坦克
            hiEnemyTank();
            // 判断 敌人的子弹 是否 击中了我们的坦克
            hitHero();

            this.repaint();

//            if(hero.shot!= null && !hero.shot.isLive){
//                System.out.println("子弹-线程停止运行了");
//                System.out.println(Thread.currentThread().getName() + "-线程停止");
//                break;
//            }
        }
    }


}
